package snapex.user.mapper;

import static org.mybatis.dynamic.sql.SqlBuilder.isEqualTo;
import static snapex.core.mapper.UserDynamicSqlSupport.credentialExpired;
import static snapex.core.mapper.UserDynamicSqlSupport.disabled;
import static snapex.core.mapper.UserDynamicSqlSupport.emailAddress;
import static snapex.core.mapper.UserDynamicSqlSupport.locked;
import static snapex.core.mapper.UserDynamicSqlSupport.mobileNumber;
import static snapex.core.mapper.UserDynamicSqlSupport.nickname;
import static snapex.core.mapper.UserDynamicSqlSupport.openId;
import static snapex.core.mapper.UserDynamicSqlSupport.passcode;
import static snapex.core.mapper.UserDynamicSqlSupport.password;
import static snapex.core.mapper.UserDynamicSqlSupport.user;
import static snapex.core.mapper.UserDynamicSqlSupport.userId;
import static snapex.core.mapper.UserDynamicSqlSupport.username;
import static snapex.core.mapper.UserDynamicSqlSupport.wechatKey;

import java.util.List;

import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.SelectProvider;
import org.apache.ibatis.type.JdbcType;
import org.mybatis.dynamic.sql.select.SelectDSL;
import org.mybatis.dynamic.sql.update.UpdateDSL;

import snapex.core.model.MyGrantedAuthority;
import snapex.core.model.User;

@Mapper
public interface UserMapper extends snapex.core.mapper.UserMapper{
       
    default User selectByUsername(String username_) {
        return SelectDSL.selectWithMapper(this::selectOne, openId, passcode, wechatKey,userId, nickname,username, password, emailAddress, mobileNumber, locked, disabled, credentialExpired)
                .from(user)
                .where(username, isEqualTo(username_))
                .build()
                .execute();
    }
    
    default User selectByUserId(String userId_) {
        return SelectDSL.selectWithMapper(this::selectOne, openId, passcode,wechatKey, userId, nickname,username, password, emailAddress, mobileNumber, locked, disabled, credentialExpired)
                .from(user)
                .where(userId, isEqualTo(userId_))
                .build()
                .execute();
    }
    
    default User selectByOpenId(String openId_) {
        return SelectDSL.selectWithMapper(this::selectOne, openId, passcode,wechatKey, userId, nickname,username, password, emailAddress, mobileNumber, locked, disabled, credentialExpired)
                .from(user)
                .where(openId, isEqualTo(openId_))
                .build()
                .execute();
    }
    
    @SelectProvider(type=UserSqlProvider.class)
    @Results(value = {
        @Result(column="resource_code", property="authority", jdbcType=JdbcType.VARCHAR)
    })
    List<MyGrantedAuthority> selectAuthorityByUsername(String username);
       
    @SelectProvider(type=UserSqlProvider.class)
    @Results(value = {
        @Result(column="resource_code", property="authority", jdbcType=JdbcType.VARCHAR)
    })
    List<MyGrantedAuthority> selectAuthorityByHashKey(String wechatKey);
    
    default int updateByHashKeySelective(User record) {
        return UpdateDSL.updateWithMapper(this::update, user)
        		.set(openId).equalToWhenPresent(record::getOpenId)
        		.set(passcode).equalToWhenPresent(record::getPasscode)
        		.set(nickname).equalToWhenPresent(record::getNickname)      		
                .set(username).equalToWhenPresent(record::getUsername)
                .set(password).equalToWhenPresent(record::getPassword)
                .set(emailAddress).equalToWhenPresent(record::getEmailAddress)
                .set(mobileNumber).equalToWhenPresent(record::getMobileNumber)
                .set(locked).equalToWhenPresent(record::getLocked)
                .set(disabled).equalToWhenPresent(record::getDisabled)
                .set(credentialExpired).equalToWhenPresent(record::getCredentialExpired)
                .where(wechatKey, isEqualTo(record::getWechatKey))
                .build()
                .execute();
    }
}